package context

import (
	"context"
	"fmt"
	"time"
)

func handle() {
	messages := make(chan int, 10)
	// task 2s消费message
	ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
	defer close(messages)
	defer cancel()

	// monit for produce
	go consume(messages, ctx)
	produce(messages)
	done(ctx)
}

func done(ctx context.Context) {
	select {
	case <-ctx.Done():
		time.Sleep(1 * time.Millisecond)
		fmt.Println("main process exit!")
	}
}

func produce(messages chan int) {
	for i := 0; i < 10; i++ {
		messages <- i
	}
}

func consume(messages chan int, ctx context.Context) {
	ticker := time.NewTicker(2 * time.Millisecond)
	for range ticker.C {
		select {
		case <-ctx.Done():
			if len(messages) == 0 {
				fmt.Println("messages handled")
			} else {
				fmt.Println("child process interrupt...")
			}
			return
		case message := <-messages:
			fmt.Printf("send message: %d\n", message)
		}
	}

}

func test() {
	ctx, cancel := context.WithCancel(context.Background())
	defer cancel()
	go func(ctx context.Context) {
		for {
			select {
			case <-ctx.Done():
				fmt.Println("监控退出，停止了...")
				return
			default:
				fmt.Println("goroutine监控中...")
				time.Sleep(1 * time.Second)
			}
		}
	}(ctx)

	time.Sleep(5 * time.Second)
	fmt.Println("可以了，通知监控停止")

	//为了检测监控过是否停止，如果没有监控输出，就表示停止了
	time.Sleep(1 * time.Second)
}

func apply() {
	ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
	defer cancel()

	go hand(ctx, 500*time.Millisecond)
	select {
	case <-ctx.Done():
		fmt.Println("main", ctx.Err())
	}
}

func hand(ctx context.Context, duration time.Duration) {
	select {
	case <-ctx.Done():
		fmt.Println("handle", ctx.Err())
	case <-time.After(duration):
		fmt.Println("process request with", duration)
	}
}

func voidCloseReRead() {
	ch := make(chan bool)
	defer close(ch)
	go func() {
		select {
		case c, ok := <-ch:
			if ok {
				fmt.Println("goroutine id:", 1, c)
			} else {
				fmt.Println("channel is closed")
			}
		}
	}()

	go func() {
		select {
		case c, ok := <-ch:
			if ok {
				fmt.Println("goroutine id:", 2, c)
			} else {
				fmt.Println("channel is closed")
			}
		}
	}()

	ch <- true

	time.Sleep(1 * time.Second)
}
